package cn.bqjr.eily.shiro.spring.boot;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Shiro缓存信息缓存
 * @param <K>
 * @param <V>
 */
public class RedisShiroCache<K, V> implements Cache<K, V> {

    private String cacheKey;
    private RedisTemplate<K, V> redisTemplate;
    private long globExpire;

    @SuppressWarnings("rawtypes")
    public RedisShiroCache(String cachePrefix, String name, RedisTemplate client, long expire) {
        this.cacheKey = cachePrefix + name + ":";
        this.redisTemplate = client;
        this.globExpire = expire;
    }

    @Override
    public V get(K key) throws CacheException {
        //redisTemplate.boundValueOps(getCacheKey(key)).expire(globExpire, TimeUnit.SECONDS);
        return redisTemplate.boundValueOps(getCacheKey(key)).get();
    }

    @Override
    public V put(K key, V value) throws CacheException {
        V old = get(key);
        redisTemplate.boundValueOps(getCacheKey(key)).set(value);
        return old;
    }

    @Override
    public V remove(K key) throws CacheException {
        V old = get(key);
        redisTemplate.delete(getCacheKey(key));
        return old;
    }

    @Override
    public void clear() throws CacheException {
        redisTemplate.delete(keys());
    }

    @Override
    public int size() {
        return keys().size();
    }

    @Override
    public Set<K> keys() {
        return redisTemplate.keys(getCacheKey("*"));
    }

    @Override
    public Collection<V> values() {
        return keys().stream()
                     .map(s -> get(s))
                     .collect(Collectors.toList());
    }

    private K getCacheKey(Object k) {
        return (K) (this.cacheKey + k);
    }
}